/*
 * UnitMap.cpp
 *
 *  Created on: 2013-1-19
 *      Author: heqiu
 */

#include "UnitMap.h"

namespace guud {
UnitMap::UnitMap() {
	m_uiShort = 0;
	m_uiLong = 0;
	m_pBuilding = NULL;
}
UnitMap::~UnitMap() {
	if (m_pBuilding != NULL) {
		delete[] m_pBuilding;
		m_pBuilding = NULL;
	}
}
bool UnitMap::init(uint32_t uiShort, uint32_t uiLong) {
	m_uiShort = uiShort;
	m_uiLong = uiLong;
	if (m_uiShort >= m_uiLong) {
		return false;
	}
	if ((uiLong - uiShort) % 2 != 0) {
		return false;
	}
	getPeak(m_stA, m_stB, m_stC, m_stD);
	m_pBuilding = new uint32_t[(m_uiLong + 1) * (m_uiLong + 1)];
	m_bitSetWay.init((m_uiLong + 1) * (m_uiLong + 1));
	for (uint32_t ui = 0; ui < (m_uiLong + 1) * (m_uiLong + 1); ui++) {
		m_pBuilding[ui] = 0;
	}
	return true;
}
void UnitMap::getPeak(GuudPoint & stA, GuudPoint & stB, GuudPoint & stC,
		GuudPoint & stD) {
	stA.m_iX = m_uiShort;
	stA.m_iY = 0;
	stB.m_iX = m_uiShort + (m_uiLong - m_uiShort) / 2;
	stB.m_iY = (m_uiLong - m_uiShort) / 2;
	stC.m_iX = (m_uiLong - m_uiShort) / 2;
	stC.m_iY = m_uiShort + (m_uiLong - m_uiShort) / 2;
	stD.m_iX = 0;
	stD.m_iY = m_uiShort;
}
bool UnitMap::bPointIn(GuudPoint & p) {
	if (m_stA.m_iX > m_stC.m_iX) {
		if (p.m_iX >= m_stD.m_iX && p.m_iX < m_stC.m_iX) {
			if (p.m_iY >= m_stD.m_iY - p.m_iX
					&& p.m_iY <= m_stD.m_iY + p.m_iX) {
				return true;
			}
		} else if (p.m_iX >= m_stC.m_iX && p.m_iX < m_stA.m_iX) {
			if (p.m_iY >= m_stD.m_iY - p.m_iX
					&& p.m_iY <= (int32_t) m_uiLong - p.m_iX) {
				return true;
			}
		} else if (p.m_iX >= m_stA.m_iX && p.m_iX <= m_stB.m_iX) {
			if (p.m_iY >= p.m_iX - m_stA.m_iX
					&& p.m_iY <= (int32_t) m_uiLong - p.m_iX) {
				return true;
			}
		}
	} else {
		if (p.m_iX >= m_stD.m_iX && p.m_iX < m_stA.m_iX) {
			if (p.m_iY >= m_stD.m_iY - p.m_iX
					&& p.m_iY <= m_stD.m_iY + p.m_iX) {
				return true;
			}
		} else if (p.m_iX >= m_stA.m_iX && p.m_iX < m_stC.m_iX) {
			if (p.m_iY >= p.m_iX - m_stD.m_iY
					&& p.m_iY <= p.m_iX + m_stD.m_iY) {
				return true;
			}
		} else if (p.m_iX >= m_stC.m_iX && p.m_iX <= m_stB.m_iX) {
			if (p.m_iY >= p.m_iX - m_stA.m_iX
					&& p.m_iY <= (int32_t) m_uiLong - p.m_iX) {
				return true;
			}
		}
	}
	return false;
}

void UnitMap::cycle(void (*func)(uint32_t, uint32_t)) {
	uint32_t uiBegin = 0;
	for (uint32_t uiLen = m_uiShort; uiLen <= m_uiLong; uiLen++) {
		for (uint32_t ui = (uiBegin + 1) / 2; ui <= m_uiShort + uiBegin / 2;
				ui++) {
			uint32_t ui2 = uiLen - ui;
			func(ui, ui2);
		}
		uiBegin++;
	}
}
void UnitMap::transformToScreen(GuudPoint stMap, GuudPoint & stScreen) {
	//(x,y)->( (x-y+s)/2 , (x+y-s) )
	stScreen.m_iX = (stMap.m_iX - stMap.m_iY + m_uiShort);
	stScreen.m_iY = (stMap.m_iX + stMap.m_iY - m_uiShort) * 2;
}
void UnitMap::transformToScreen(GuudFloatPoint stMap,
		GuudFloatPoint & stScreen) {
	//(x,y)->( (x-y+s)/2 , (x+y-s) )
	stScreen.m_fX = (stMap.m_fX - stMap.m_fY + m_uiShort);
	stScreen.m_fY = (stMap.m_fX + stMap.m_fY - m_uiShort) * 2;
}

void UnitMap::transformToMap(GuudPoint stScreen, GuudPoint & stMap) {
	//( (2a+b)/2 , (b-2a+2s)/2 )  <- (a,b)
	stMap.m_iX = (stScreen.m_iX + stScreen.m_iY / 2) / 2;
	stMap.m_iY = (stScreen.m_iY / 2 - stScreen.m_iX + 2 * m_uiShort) / 2;
}
void UnitMap::transformToMap(GuudFloatPoint stScreen, GuudFloatPoint & stMap) {
	//( (2a+b)/2 , (b-2a+2s)/2 )  <- (a,b)
	stMap.m_fX = (stScreen.m_fX + stScreen.m_fY / 2) / 2;
	stMap.m_fY = (stScreen.m_fY / 2 - stScreen.m_fX + 2 * m_uiShort) / 2;
}
uint32_t UnitMap::getBuilding(uint32_t uiX, uint32_t uiY) {
	if (uiX > m_uiLong || uiY > m_uiLong) {
		return 0;
	}
	uint32_t uiPos = uiX * (m_uiLong + 1) + uiY;
	return m_pBuilding[uiPos];
}
bool UnitMap::testBuilding(UnitBuilding & stNode) {
	for (uint32_t ui = 0; ui < stNode.m_xLen; ui++) {
		for (uint32_t uj = 0; uj < stNode.m_yLen; uj++) {
			GuudPoint stPoint(stNode.m_stPos.m_iX + ui,
					stNode.m_stPos.m_iY + uj);
			if (!bPointIn(stPoint)) {
				return false;
			}
			//已经有建筑
			if (getBuilding(stPoint.m_iX, stPoint.m_iY) > 0) {
				return false;
			}
		}
	}
	return true;
}
bool UnitMap::setBuilding(UnitBuilding & stNode) {
	if (testBuilding(stNode)) {
		for (uint32_t ui = 0; ui < stNode.m_xLen; ui++) {
			for (uint32_t uj = 0; uj < stNode.m_yLen; uj++) {
				uint32_t uiX = stNode.m_stPos.m_iX - ui;
				uint32_t uiY = stNode.m_stPos.m_iY - uj;
				uint32_t uiPos = uiX * (m_uiLong + 1) + uiY;
				m_pBuilding[uiPos] = stNode.m_iId;
			}
		}
		return true;
	}
	return false;
}
void UnitMap::printBuilding() {
	uint32_t uiBegin = 0;
	for (uint32_t uiLen = m_uiShort; uiLen <= m_uiLong; uiLen++) {
		for (uint32_t ui = (uiBegin + 1) / 2; ui <= m_uiShort + uiBegin / 2;
				ui++) {
			uint32_t ui2 = uiLen - ui;
			uint32_t uiPos = ui * (m_uiLong + 1) + ui2;
			if (m_pBuilding[uiPos] > 0) {
				printf("x:%d y:%d building:%d\n", ui, ui2, m_pBuilding[uiPos]);
			}
		}
		uiBegin++;
	}
}
}

